﻿using System.Configuration;

namespace System.Web.Mvc
{
	[AttributeUsage(AttributeTargets.Class)]
	public class RedirectHttpsAttribute : ActionFilterAttribute
	{
		#region Properties
		private static string _DisableHttpsRedirect;
		/// <summary>
		/// When true, forcing a redirect to a secure page is suppressed.
		/// </summary>
		/// <remarks>
		/// This value can be set in the config file under the "DisableHttpsRedirect" app setting.
		/// </remarks>
		public static bool DisableHttpsRedirect
		{
			get
			{
				if (string.IsNullOrEmpty(_DisableHttpsRedirect))
				{
					_DisableHttpsRedirect = (ConfigurationManager.AppSettings["DisableHttpsRedirect"] ?? "False");
				}

				bool retValue;
				if (!bool.TryParse(_DisableHttpsRedirect, out retValue))
				{
					retValue = false;
				}

				return retValue;
			}

			set
			{
				_DisableHttpsRedirect = value.ToString();
			}
		}

		private static string _SecurePort;

		/// <summary>
		/// When set to a number, explicitly declares the port of the URL in the redirect string.
		/// When set to -1, uses the default protocol port (no port number in the string)
		/// </summary>
		/// <remarks>
		/// This value can be set in the config file under the "SecurePort" app setting.
		/// </remarks>
		public static int SecurePort
		{
			get
			{
				if (string.IsNullOrEmpty(_SecurePort))
				{
					_SecurePort = (ConfigurationManager.AppSettings["SecurePort"] ?? "-1");
				}

				int retValue;
				if (!int.TryParse(_SecurePort, out retValue))
				{
					retValue = -1;
				}

				return retValue;
			}

			set
			{
				_SecurePort = value.ToString();
			}
		}
		#endregion

		public override void OnResultExecuting(ResultExecutingContext filterContext)
		{
			//Allow the redirect to be disabled in the config file.  This may be necessary for testing purposes.
			if (!filterContext.HttpContext.Request.IsSecureConnection &&
			 !DisableHttpsRedirect)
			{
				//replace the contents of the nonsecure string with the proper protocol and port number.
				UriBuilder ub = new UriBuilder(filterContext.HttpContext.Request.Url);
				ub.Scheme = "https";
				ub.Port = SecurePort;


				//direct the context to redirect to the proper secure channel.
				filterContext.Result = new RedirectResult(ub.ToString());
				filterContext.Result.ExecuteResult(filterContext);
			}

			return;
		}
	}
}